package com.example.design_pattern.observer;

import java.util.ArrayList;
import java.util.List;

// 本案例，演示的是观察者模式

// 定义主题接口
interface Subject {
    void registerObserver(Observer observer); // 注册观察者
    void removeObserver(Observer observer);  // 移除观察者
    void notifyObservers();  // 通知观察者
}

// 定义观察者接口
interface Observer {
    void update(String message); // 更新方法
}

// 具体的主题类
class ConcreteSubject implements Subject {

    // 主题也是一个类。类就是一个创建实例对象的模板。而实例对象就是一个装状态和方法的地方。
    // 这就是实例对象里面装状态的另一块小区域。它里面主要是装观察者的。
    private List<Observer> observers = new ArrayList<>();

    // 注册观察者，就是把某个观察者实例对象，装进装观察者的List里面
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    // 通知观察者的话，其实就是遍历所有的观察者，对每个观察者都做xx逻辑。
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update("Subject is updated!");
        }
    }
}

// 具体的观察者类
class ConcreteObserver implements Observer {
    private String name;

    // 构造函数
    public ConcreteObserver(String name) {
        this.name = name;
    }

    // 这个方法是干嘛的？是当观察者收到新消息之后，就自动触发这个方法吗???
    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

public class ObserverTest {
    public static void main(String[] args) {
        // 创建主题
        ConcreteSubject subject = new ConcreteSubject();

        // 创建观察者
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        // 注册观察者。一个主体注册了两个观察者。
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        // 主题更新，通知观察者
        subject.notifyObservers();
    }
}


// 备注：观察者设计模式，一般用于什么场景下
// 观察者设计模式通常用于以下场景：
//
//1. **事件处理/通知机制**: 当一个对象的状态发生变化时，需要通知其他对象进行相应的处理。例如，GUI 应用程序中的按钮点击事件，文件系统中的文件变更通知等。
//2. **发布-订阅模型**: 当一个对象（发布者或主题）有重要的信息需要传递给多个对象（订阅者或观察者）时，可以使用观察者模式。例如，消息队列中的消息发布与订阅，异步通信中的回调机制等。
//3. **解耦**: 观察者模式可以降低对象之间的耦合度。发布者和订阅者之间不需要直接相互通信，而是通过一个中介（主题）来进行交互，从而提高了系统的灵活性和可维护性。
//4. **实时更新**: 当一个对象的状态发生变化时，所有关注该对象的观察者可以及时获得更新，从而保持数据的一致性。例如，股票市场中的股票价格变动通知，即时通讯软件中的在线状态更新等。

